home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
IPTUT002.ZIP
/
iptut002.txt
< prev
Wrap
Text File
|
1995-06-12
|
8KB
|
203 lines
************************************************************************
* Jouni Miettunen * jon@stekt.oulu.fi * Oulu * Finland * Europe * 1995 *
Intermediate Programmer Tutorial #002
Copyright (c) 1995 by Jouni Miettunen
Version 1.2 - 12 June 1995
Turbo C++ 3.0 Bugs and How to Deal with Them
** INTRODUCTION
I code small DOS applications, usually with my own GUI library. None of
the programs need to be realtime, handle multiple huge datafiles or do
several things at the same time. Still they need to function correctly.
The purpose of this tutorial is to collect information about TC3 bugs,
peculiar or annoying features and how to cope with them. If you have
some more information, please contact me and I'll update this document.
I have already released one buggy program, when I couldn't make the
final "clean" compilation thanx to constant compiler crashes. I'm sure
the tone of this document will reveal you what I think about such a
product and a company.
** THE GOOD, THE BAD AND TURBO C++ 3.0
My Chosen Compiler (TM) is TC3 and I am not too happy with it. When I
have afford, I'll buy Watcom C/C++ compiler.. in case I'll continue
writing DOS programs.
The bad points are that Borland doesn't support TC3 anymore and that it
is buggy. On the other hand this is quite understandable remembering it
was released 1992 and is a DOS program. The manual isn't quite adequate
even as an elbow rest and the online Reference Guide doesn't fill my
needs.
The good points are that it was reasonably inexpensive, is reasonably
fast, generates reasonably tight code and usually works just fine. The
most important feature is IDE (Integrated Development Environment ie. a
Text User Interface) to help developing, debugging, compiling and
linking programs in the same nice visual environment. Code hilighting is
a feature I've found very useful.
You also has to remember that TC3 is an ANSI C compiler, supports the
basic features of C++ and comes with a royalty free full graphics
library (BGI). The money I spent buying it was not wasted, I just
thought I'd get a perfect program. Instead I got a rude awakening..
** WINERROR 3
TC3 supports several screen resolutions (24/43/50 lines) and thus has
some internal information about the locations of its windows. Sometimes
this info gets corrupted and fools TC3 to try to open windows or dialogs
outside the visible screen area. The result is compiler crash. If you
get lucky, only the compiler will crash (winerror = 3) and you can try
again, but occasionally also the whole system crashes needing a reboot.
The solution is to every now and then close all open windows and reopen
those you need. This is done by selecting Window menu and there item
Close All. Another possibility is to delete the desktop file (*.dsk)
before starting TC3.
Window:Close All - just select this once
** NOT ENOUGH MEMORY TO START
If you use IDE, but don't have enough memory to load datafiles or even
start the program, disable Debugger. Also remember to disable the two
related debugging options.
Options:Compiler:Advanced Code Generation:Line Numbers Debug Info - OFF
Options:Compiler:Advanced Code Generation:Debug Info In OBJs - OFF
Options:Debugger:Source Debugging - OFF
** NOT ENOUGH MEMORY TO DEBUG
Sometimes you would like to debug your program with the build-in
debugger, but can't, since there's not enough free memory.. or that's
what TC3 thinks.
By default only 64K is reserved for your program's dynamically allocated
data. Fortunately you can increase this value by yourself and debug the
program just fine. Still you have to remember that there is a real limit
in the amount of available memory that can't be changed by any compiler
options.
Options:Debugger:Program Heap Size - write a new value
I'd recommend using values under 640K, the amount of conventional DOS
memory. If you need more, don't use TC3.
** BUILT-IN ASSEMBLER
Turbo C comes with a built-in assembler. The manual index says to see
"The online document" mentioning filename UTIL.DOC, but the correct file
is BASM.DOC.
There are few things to remember about BASM syntax: labels have to be
outside asm {} block and the comments have to be C or C++ comments.
SkipScanLine:
waitHRTend:
asm {
in al,dx
test al,01h
jz waitHRTend
}
waitHRTstart:
asm {
in al,dx
test al,01h
jnz waitHRTstart
loop short SkipScanLine /* wait till cx scan lines passed */
}
The inline assembler is a 16-bit assembler and supports only 8086 code
generation. However placing the 66h "operand size override" on the line
before the instruction can force it to be understood as 32-bit.
asm db 0x66
asm rep stosw // rep stosd
** 64K LIMIT
The most frustrating thing in DOS programming is the memory management
and especially the long and hard cursed 64k limitation in.. everything!
If you read a file into a buffer, you can read only the first 64k. If
you print a text string, you can print only the first 64k.
The solution seems to be using huge pointers, as suggested in various
referencies. The problem is that huge pointers are really slow.. but the
problem might be the solution, if you know what you're doing: using huge
pointers mean in practice that you use far pointers that are normalized
everytime their value is changed. You can do this yourself, if you can
identify the moments, when it is necessary.
** INCREMENTING POINTERS
There is something strange in the pointer incrementation.. According to
the ANSI C specification, which TC3 is supposed to obey, the following
code examples should do exactly the same thing: add 2 into the value of
the variable.
char far *ch;
ch += 2;
ch = ch + 2;
However TC3 generates different code for them:
;
; ch += 2;
;
add word ptr [bp-4],2
;
; ch = ch + 2;
;
mov ax,word ptr [bp-2]
mov dx,word ptr [bp-4]
add dx,2
mov word ptr [bp-2],ax
mov word ptr [bp-4],dx
At first sight this might seem ok: both add the requested value into the
offset of the variable (and offset wraps around). The first example even
might seem to be a better choice, since it generates less "unused" code.
However in practise I've found the second way to be more reliable..
Occasionally the first one just doesn't seem to be doing what the code
says it to do, especially when incrementing char far *pointers.
Since I don't have any real asm manual, I can't tell at the moment what
is the difference in operation. First one is an indirect addition and
the second one is a direct addition with a register. Should RTFM a bit..
** HISTORY
1.0 Winerror 3, Not enough memory to start
1.1 BASM, Pointer normalization
1.2 Not enough memory to debug, Pointer incrementation
** DISCLAIMER
Please note I have written this tutorial in good faith, but I cannot
guarantees its contents. I think it's all correct, that things really
work this way and could be taken care of like this. If something goes
wrong, that will be your problem, not mine. You have been warned.
Additions, fixes and spelling and grammar instructions are most welcome.
Hope you could find this useful. This tutorial is copyrighted, but
freely redistributable material.
** AUTHOR
Mr. Jouni Miettunen
Rautatienkatu 20 A 10
FIN-90100 OULU
FINLAND - EUROPE
* Jouni Miettunen * jon@stekt.oulu.fi * Oulu * Finland * Europe * 1995 *
************************************************************************